package battleroom;

import com.jme3.app.SimpleApplication;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResults;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.scene.shape.Box;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;


/**
 *
 * @author zach
 */
public class StarControl extends AbstractControl{
    BulletAppState bulletAppState;
    public int s; //size of the stars
    private boolean showOutline = false;
    private Spatial outline;
       
    
    StarControl(int size)
    {
        s=size;
    }
    
    public void toggleShowOutline(boolean toggle, Main app)
    {
        showOutline = toggle;
        
        if(showOutline)
        {
            app.getUtil().outlineSpatial(getSpatial(), 1.5f, ColorRGBA.White);
        }else{
            app.getUtil().destroyOutline(getSpatial());
        }
    }
    
    public boolean isValidLocation(float x, float y, float z){
        
        return true;
    }
    
    @Override
    public void write(JmeExporter ex) throws IOException {
        super.write(ex);
    }
    
    @Override
    public void read(JmeImporter im) throws IOException {
        super.read(im);
    }

    public int size(){return this.s;}
    
    public boolean isOnFace(Vector3f normal, Vector3f point)
    {
        if(!normal.isUnitVector())
        {
            normal.normalizeLocal();
        }
        
        Vector3f max = new Vector3f(size(), size(), size());
        max = excludeParallelComponent(normal, max.add(getFaceCenter(normal)));
        Vector3f min = new Vector3f(-size(), -size(), -size());
        min = excludeParallelComponent(normal, min.add(getFaceCenter(normal)));
        
        if(point.getX() > max.getX() && max.getX() != 0)
        {
            return false;
        }
        
        if(point.getY() > max.getY() && max.getY() != 0)
        {
            return false;
        }
        
        if(point.getZ() > max.getZ() && max.getZ() != 0)
        {
            return false;
        }
        
        if(point.getX() < min.getX() && max.getX() != 0)
        {
            return false;
        }
        
        if(point.getY() < min.getY() && max.getY() != 0)
        {
            return false;
        }
        
        if(point.getZ() < min.getZ() && max.getZ() != 0)
        {
            return false;
        }
        
        return true;
    }
    
    //Don't really know where this should go... guess i'll put it here
    //This returns vector u with a 0 in the component that vector n is 
    //parallel to
    static public Vector3f excludeParallelComponent(Vector3f n, Vector3f u)
    {
        if(!n.isUnitVector())
        {
            n.normalizeLocal();
        }
        
        if(PlayerState.isCloseTo(Math.abs(n.getX()), 1f, .25f))
        {
            u.multLocal(new Vector3f(0, 1, 1));
        }else if(PlayerState.isCloseTo(Math.abs(n.getY()), 1f, .25f)){
            u.multLocal(new Vector3f(1, 0, 1));            
        }else if(PlayerState.isCloseTo(Math.abs(n.getZ()), 1f, .25f)){
            u.multLocal(new Vector3f(1, 1, 0));            
        }
        
        return u;
    }
    
    static public Vector3f excludeNonParallelComponent(Vector3f n, Vector3f u)
    {
        if(!n.isUnitVector())
        {
            n.normalizeLocal();
        }
        
        if(PlayerState.isCloseTo(Math.abs(n.getX()), 1f, .25f))
        {
            u.multLocal(new Vector3f(1, 0, 0));
        }else if(PlayerState.isCloseTo(Math.abs(n.getY()), 1f, .25f)){
            u.multLocal(new Vector3f(0, 1, 0));            
        }else if(PlayerState.isCloseTo(Math.abs(n.getZ()), 1f, .25f)){
            u.multLocal(new Vector3f(0, 0, 1));            
        }
        
        return u;
    }
    
    public Vector3f getFaceCenter(Vector3f normal)
    {
        if(!normal.isUnitVector())
        {
            normal.normalizeLocal();
        }
        
        return getSpatial().getLocalTranslation().add(normal.mult(size()));
    }


    public Control cloneForSpatial(Spatial spatial) {
        final StarControl control = new StarControl(size());
    /* Optional: use setters to copy userdata into the cloned control */
    // control.setIndex(i); // example
    control.setSpatial(spatial);
    return control;
    }
    
    @Override
    public void setSpatial(Spatial spatial) {
        super.setSpatial(spatial);
      
    }

    @Override
    protected void controlUpdate(float tpf) {
        /** Implement your spatial's behaviour here.
    * From here you can modify the scene graph and the spatial
    * (transform them, get and set userdata, etc).
    * This loop controls the spatial while the Control is enabled. */
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {
        /* Optional: rendering manipulation (for advanced users) */
    }
}
